/**
 * FileName: AvoidResumitAspect
 * Author:   xianggang
 * Date:     2021/11/30
 * Description:
 */
package com.adinnet.api.common.utils;

import com.adinnet.common.utils.UUIDUtil;
import com.adinnet.core.exception.BizException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.annotation.Resource;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.TimeUnit;

/**
 * 〈〉
 * @author xianggang
 * @create 2021/11/30
 */
@Aspect
@Component
public class AvoidResumitAspect {
    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 定义匹配规则，以便于后续拦截直接拦截submit方法，不用重复表达式
     */
    @Pointcut(value = "@annotation(AvoidReSubmit)")
    public void submit() {
    }

    @Before("submit()&&@annotation(avoidReSubmit)")
    public void doBefore(JoinPoint joinPoint, AvoidReSubmit avoidReSubmit) throws Exception {

        // 拼装参数
        StringBuffer sb = new StringBuffer();
        for(Object object : joinPoint.getArgs()){
            sb.append(object);
        }

        String key = md5(sb.toString());
        long expireTime = avoidReSubmit.expireTime();
        ValueOperations valueOperations = redisTemplate.opsForValue();
        Object object = valueOperations.get(key);
        if(null != object){
            throw new BizException("您已经提交了请求，请不要重复提交哦！");
        }
        valueOperations.set(key, 1, expireTime, TimeUnit.MILLISECONDS);
    }

    @Around("submit()&&@annotation(avoidReSubmit)")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint, AvoidReSubmit avoidReSubmit) throws Throwable {
        System.out.println("环绕通知：");
        Object result = null;
        result = proceedingJoinPoint.proceed();
        return result;
    }

    @After("submit()")
    public void doAfter() {
        System.out.println("******拦截后的逻辑******");
    }

    private String md5(String str){
        if (str == null || str.length() == 0) {
            throw new IllegalArgumentException("String to encript cannot be null or zero length");
        }
        StringBuffer hexString = new StringBuffer();
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            byte[] hash = md.digest();
            for (int i = 0; i < hash.length; i++) {
                if ((0xff & hash[i]) < 0x10) {
                    hexString.append("0" + Integer.toHexString((0xFF & hash[i])));
                } else {
                    hexString.append(Integer.toHexString(0xFF & hash[i]));
                }
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return hexString.toString();
    }
}
